# UDS诊断CAN报文收发全解析（ISO 14229 + ISO 15765-2）
uds_can_services = [
    {
        "id": 0x10,
        "name": "DiagnosticSessionControl",
        "request": "02 10 [session]",
        "response": "06 50 [session] [P2_max_H] [P2_max_L] [P2*_max_H] [P2*_max_L]",
        "negative": "03 7F 10 [NRC]",
        "remark": "会话控制，session:01=默认,02=编程,03=扩展, P2/P2*单位为ms"
    },
    {
        "id": 0x11,
        "name": "ECUReset",
        "request": "02 11 [type]",
        "response": "03 51 [type] [pwr_down]",
        "negative": "03 7F 11 [NRC]",
        "remark": "复位控制，type:01=硬复位,02=点火复位,04=快速断电, pwr_down:断电时间(秒)"
    },
    {
        "id": 0x22,
        "name": "ReadDataByIdentifier",
        "request": "04 22 [DID_H] [DID_L]",  # 示例: 读取DID F190
        "response_sf": "06 62 [DID_H] [DID_L] [d0] [d1]",  # 单帧响应
        "response_mf": ["10 0B 62 [DID_H] [DID_L] [d0-d5]", "21 [d6-d13]", "22 [d14]..."],  # 多帧响应
        "negative": "03 7F 22 [NRC]",
        "remark": "DID读取，常用DID:F189=VIN, F190=ECU名称, F12C=里程"
    },
    {
        "id": 0x27,
        "name": "SecurityAccess",
        "request_1": "03 27 [level|0x01]",  # 请求种子
        "response_1": "06 67 [level|0x01] [seed_h] [seed_l]",
        "request_2": "04 27 [level|0x02] [key_h] [key_l]",  # 发送密钥
        "response_2": "02 67 [level|0x02]",
        "negative": "03 7F 27 [NRC]",
        "remark": "安全访问，level奇数=种子请求，偶数=密钥发送，密钥=种子^0x1234(示例算法)"
    },
    {
        "id": 0x2E,
        "name": "WriteDataByIdentifier",
        "request": "06 2E [DID_H] [DID_L] [d0] [d1]",  # 示例: 写DID F120
        "response": "03 6E [DID_H] [DID_L]",
        "negative": "03 7F 2E [NRC]",
        "remark": "需先通过0x27解锁，写入后需ECUReset生效"
    },
    {
        "id": 0x3E,
        "name": "TesterPresent",
        "request": "02 3E 80",  # 抑制响应的心跳
        "response": "NONE",
        "remark": "每2秒发送一次维持会话，80=抑制响应位"
    },
    {
        "id": 0x19,
        "name": "ReadDTCInformation",
        "request": "04 19 [sub] [status]",  # 子功能+状态掩码
        "response": "0F 59 [sub] [status] [dtc1] [dtc2] [dtc3] [snap]...",  # DTC+快照数据
        "negative": "03 7F 19 [NRC]",
        "remark": "sub:02=读DTC快照, status:FF=所有状态DTC"
    },
    {
        "id": 0x14,
        "name": "ClearDiagnosticInformation",
        "request": "04 14 [group_h] [group_l]",  # FFFF=所有DTC
        "response": "02 54",
        "negative": "03 7F 14 [NRC]",
        "remark": "清除后需ECUReset使DTC状态复位"
    },
    {
        "id": 0x31,
        "name": "RoutineControl",
        "request": "05 31 [mode] [RID_H] [RID_L] [param]",  # 例程控制
        "response": "04 71 [mode] [RID_H] [RID_L] [result]",
        "negative": "03 7F 31 [NRC]",
        "remark": "mode:01=启动,02=停止,03=结果; RID:0201=自检,FF00=擦除内存"
    },
    # ========== 数据传输服务组 ==========
    {
        "id": 0x34,
        "name": "RequestDownload",
        "request": "07 34 [format] [addr_h] [addr_l] [size_h] [size_l]",
        "response": "04 74 [max_block] [format]",
        "remark": "format:高4位地址长度,低4位数据长度; max_block:最大块大小"
    },
    {
        "id": 0x36,
        "name": "TransferData",
        "request": ["10 1A 36 00 [data0-5]", "21 [data6-13]", "22 [data14]..."],  # 多帧传输
        "response": ["10 0A 76 00 [data0-5]", "21 [data6-13]"],  # 块序号递增
        "remark": "00=首块,01/02...=后续块, 每块最多63字节"
    },
    {
        "id": 0x37,
        "name": "RequestTransferExit",
        "request": "01 37",
        "response": "01 77",
        "remark": "结束刷写会话"
    }
]

# UDS通用参数说明
uds_common = {
    "can_id": {
        "physical": "0x7E0",  # 物理寻址发送
        "functional": "0x7DF",  # 功能寻址广播
        "response": "0x7E8"   # ECU响应地址
    },
    "nrc_codes": {
        "0x11": "服务不支持",
        "0x12": "子功能不支持",
        "0x13": "报文长度错误",
        "0x22": "条件不满足",
        "0x31": "请求超范围",
        "0x33": "安全访问拒绝",
        "0x35": "密钥无效",
        "0x78": "响应挂起"  # 需等待后续响应
    },
    "tp_protocol": {
        "single_frame": "0[length] [data]",    # 单帧
        "first_frame": "1[length_h][length_l] [data]",  # 首帧(12位长度)
        "consecutive": "2[seq] [data]",        # 连续帧(seq从1开始)
        "flow_control": "3[type][bs][st]"      # 流控(00=继续, bs=块大小, st=间隔ms)
    }
}
]